import json

import os
from typing import Dict, Any, List, Optional
from pathlib import Path

from ..utils.logger import get_logger
logger = get_logger("driver.core")        # 获取logger实例

class ConfigManager:
    """配置管理器（单例模式）"""

    _instance = None
    _initialized = False

    def __new__(cls, config_file: Optional[str] = None, default_config_file: str = "driver/config/driverconfig.json"):
        """
        实现单例模式
        """
        if cls._instance is None:
            cls._instance = super(ConfigManager, cls).__new__(cls)
        return cls._instance

    def __init__(self, config_file: Optional[str] = None, default_config_file: str = "driver/config/driverconfig.json"):
        """
        初始化配置管理器

        Args:
            config_file: 用户自定义配置文件路径（可选）
            default_config_file: 默认配置文件路径（仅作参考）
        """
        # 防止重复初始化
        if ConfigManager._initialized:
            return

        try:
            self.default_config_file = default_config_file
            self.config_data: Dict[str, Any] = {}

            # 如果提供了用户配置文件，则加载用户配置
            if config_file:
                self.config_file = config_file
                self.load_config()
            else:
                # 否则使用默认配置文件路径
                # 使用基于模块文件位置的方式处理默认配置文件路径
                current_dir = os.path.dirname(os.path.abspath(__file__))
                driver_root = os.path.dirname(current_dir)
                self.config_file = os.path.join(driver_root, "config", "driverconfig.json")
                self.load_config()

            ConfigManager._initialized = True
        except Exception as e:
            logger.error(f"ConfigManager initialization failed: {e}")
            raise

    def load_config(self) -> bool:
        """
        加载配置文件（只加载用户配置，不合并默认配置）

        Returns:
            bool: 是否加载成功
        """
        try:
            if os.path.exists(self.config_file):
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    self.config_data = json.load(f)
                logger.info(f"Config loaded from {self.config_file}")
                return True
            else:
                logger.warning(f"Config file {self.config_file} not found")
                # 初始化为空配置
                self.config_data = {}
                return False
        except json.JSONDecodeError as e:
            logger.error(f"Config file {self.config_file} format error: {e}")
            return False
        except Exception as e:
            logger.error(f"Error loading config from {self.config_file}: {e}")
            return False

    def load_default_config(self) -> bool:
        """
        加载默认配置文件（仅作参考，不实际使用）

        Returns:
            bool: 是否加载成功
        """
        logger.info("Default config is only for reference, not actually loaded or merged")
        return True

    def load_user_config(self) -> bool:
        """
        加载用户配置文件（与load_config功能相同）

        Returns:
            bool: 是否加载成功
        """
        return self.load_config()

    def _merge_config(self, base_config: Dict[str, Any], user_config: Dict[str, Any]) -> None:
        """
        合并配置（保留此方法以保持接口兼容性，但不实际使用）

        Args:
            base_config: 基础配置
            user_config: 用户配置
        """
        pass

    def save_config(self) -> bool:
        """
        保存配置到文件

        Returns:
            bool: 是否保存成功
        """
        try:
            # 确保目录存在
            os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(self.config_data, f, ensure_ascii=False, indent=2)
            logger.info(f"Config saved to {self.config_file}")
            return True
        except Exception as e:
            logger.error(f"Error saving config to {self.config_file}: {e}")
            return False

    def get(self, key: str, default: Any = None) -> Any:
        """
        获取配置项的值

        Args:
            key: 配置项键名（支持点号分隔的嵌套键名，如 "database.host"）
            default: 默认值

        Returns:
            配置项的值或默认值
        """
        keys = key.split('.')
        value = self.config_data

        try:
            for k in keys:
                value = value[k]
            return value
        except (KeyError, TypeError):
            return default

    def set(self, key: str, value: Any) -> None:
        """
        设置配置项的值

        Args:
            key: 配置项键名（支持点号分隔的嵌套键名，如 "database.host"）
            value: 配置项值
        """
        keys = key.split('.')
        config = self.config_data

        # 遍历到倒数第二个键，确保路径存在
        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]

        # 设置最后一个键的值
        config[keys[-1]] = value

    def get_all(self) -> Dict[str, Any]:
        """
        获取所有配置

        Returns:
            Dict[str, Any]: 所有配置数据
        """
        return self.config_data.copy()

    def get_devices_config(self, protocol: str) -> List[Dict[str, Any]]:
        """
        获取指定协议的设备配置列表

        Args:
            protocol: 协议类型

        Returns:
            List[Dict[str, Any]]: 设备配置列表
        """
        devices = self.config_data.get("devices", {})
        return devices.get(protocol, [])

    def add_device_config(self, protocol: str, device_config: Dict[str, Any]) -> bool:
        """
        添加设备配置

        Args:
            protocol: 协议类型
            device_config: 设备配置

        Returns:
            bool: 是否添加成功
        """
        try:
            if "devices" not in self.config_data:
                self.config_data["devices"] = {}

            if protocol not in self.config_data["devices"]:
                self.config_data["devices"][protocol] = []

            self.config_data["devices"][protocol].append(device_config)
            logger.info(f"Device config added for protocol {protocol}")
            return True
        except Exception as e:
            logger.error(f"Error adding device config for protocol {protocol}: {e}")
            return False

    def remove_device_config(self, protocol: str, device_id: str) -> bool:
        """
        移除设备配置

        Args:
            protocol: 协议类型
            device_id: 设备ID

        Returns:
            bool: 是否移除成功
        """
        try:
            if "devices" not in self.config_data:
                return False

            if protocol not in self.config_data["devices"]:
                return False

            devices = self.config_data["devices"][protocol]
            for i, device in enumerate(devices):
                if device.get("device_id") == device_id:
                    del devices[i]
                    logger.info(f"Device config removed for protocol {protocol}, device_id {device_id}")
                    return True

            logger.warning(f"Device config not found for protocol {protocol}, device_id {device_id}")
            return False
        except Exception as e:
            logger.error(f"Error removing device config for protocol {protocol}, device_id {device_id}: {e}")
            return False


def get_config_manager(config_file: Optional[str] = None) -> ConfigManager:
    """
    获取配置管理器实例（全局访问点）

    Args:
        config_file: 配置文件路径（可选）

    Returns:
        ConfigManager: 配置管理器实例
    """
    return ConfigManager(config_file=config_file)